package org.jdesktop.databuffer.json;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import org.apache.log4j.Logger;
import org.jdesktop.databuffer.DataColumn;
import org.jdesktop.databuffer.DataSet;
import org.jdesktop.databuffer.DataTable;
import net.sf.json.*;

public class DataSet2Json {
	private static final Logger ourLogger = Logger
			.getLogger(DataSet2Json.class);

	public static String toJsonString(DataSet info) {
		return toJson(info).toString();
	}

	public static JSONObject toJson(DataSet info) {
		JSONObject jsonObj = toJsonObject(info);
		return jsonObj;
	}

	public static String toJsonString(DataTable inblock) {
		JSONObject jsonObj = toJsonObject(inblock);
		return jsonObj.toString();
	}

	public static JSONObject toJsonObject(DataSet info) {
		try {
			JSONObject jsonEi = new JSONObject();

			HashMap eiBlocks = new HashMap();


			List<DataTable> blocks = info.getTables();
			for (DataTable table : blocks) {
				eiBlocks.put(table.getName(), toJsonObject(table));
			}

			jsonEi.put("name", info.getName());
			jsonEi.put("descName", info.getDescName());
			jsonEi.put("msg", info.getMsg());
			jsonEi.put("msgKey", info.getMsgKey());
			jsonEi.put("detailMsg", info.getDetailMsg());
			jsonEi.put("status", new Integer(info.getStatus()));

			Map attr = info.getAttr();
			if (attr != null) {
				jsonEi.put("attr", info.getAttr());
			}

			jsonEi.put("blocks", eiBlocks);

			return jsonEi;
		} catch (JSONException ex) {
			throw new IllegalStateException(ex.getMessage());
		}
	}

	public static JSONObject toJsonObject(DataTable eiBlock) {
		try {
			JSONObject block = new JSONObject();
			Map attr = eiBlock.getAttr();
			if (attr != null) {
				block.put("attr", eiBlock.getAttr());
			}
		
			Map<String,DataColumn> map = eiBlock.getDataColumns();			
			List list = new ArrayList();
			
			Iterator keyIt = map.keySet().iterator();
			while (keyIt.hasNext()) {
				String name = (String) keyIt.next();
				DataColumn dc = map.get(name);
				list.add(dc);			
			}			
			
			block.put("meta", toJsonObject(list));	
			
			JSONArray records = new JSONArray();	
			
			for(int row = 0;row<eiBlock.getRowCount();row++){
				JSONArray record = new JSONArray();
				for (int col=0;col< list.size();col++) {
					Object property = eiBlock.getCell(row,((DataColumn)list.get(col)).getName());
					if (property != null) {
						if(((DataColumn)list.get(col)).getType() .equals(Date.class)){
							DateFormat format = new SimpleDateFormat(((DataColumn)list.get(col)).getDateFormat()); 							
							record.add(col, format.format(property));
						}else{
							record.add(col, property.toString());
						}					
					} else
						record.add(col, JSONNull.getInstance());
				}
				records.add(row, record);
			}
	
			block.put("rows", records);
			return block;
		} catch (JSONException ex) {
			ourLogger.error(ex.getMessage(), ex);
			throw new IllegalStateException(ex.getMessage());
		}
	}

	public static JSONObject toJsonObject(List list) {
		JSONObject columns = new JSONObject();
		try {

			JSONArray columnArray = new JSONArray();
			
			int idx = 0;
			for(Object dc : list){
				if (dc != null) {
					columnArray.add(idx, toJsonObject((DataColumn)dc, idx));
					idx++;
				}	
			}
			columns.put("columns", columnArray);

			return columns;
		} catch (JSONException ex) {
			ourLogger.error(ex.getMessage(), ex);
			throw new IllegalStateException(ex.getMessage());
		}
	}

	public static JSONObject toJsonObject(DataColumn eiColumn, int index) {
		try {
			JSONObject jsonColumn = new JSONObject();

			jsonColumn.put("pos", new Integer(index));

			String tempString = eiColumn.getName();
			if (tempString != null) {
				jsonColumn.put("name", tempString);
			}
			if ((tempString = eiColumn.getDescName()) != null) {
				jsonColumn.put("descName", tempString);
			}
			//tempString = eiColumn.getType().toString();
			tempString = eiColumn.getType().getPackage().getName() +"."+ eiColumn.getType().getSimpleName() ;
			if ((tempString != null)) {
				jsonColumn.put("type", tempString);
			}

			if (eiColumn.getScaleLength() > 0) {
				jsonColumn.put("scaleLength",
						new Integer(eiColumn.getScaleLength()));
			}
			if (eiColumn.getFieldLength() > 0) {
				jsonColumn.put("fieldLength",
						new Integer(eiColumn.getFieldLength()));
			}

			if ((tempString = eiColumn.getRegex()) != null) {
				jsonColumn.put("regex", tempString);
			}
			if ((tempString = eiColumn.getFormatter()) != null) {
				jsonColumn.put("formatter", tempString);
			}
			tempString = eiColumn.getEditor();
			if ((tempString != null) && (!"text".equals(tempString))) {
				jsonColumn.put("editor", tempString);
			}
			int tempInteger = eiColumn.getMinLength();
			if (tempInteger > 0) {
				jsonColumn.put("minLength", new Integer(tempInteger));
			}
			if ((tempInteger = eiColumn.getMaxLength()) > 0) {
				jsonColumn.put("maxLength", new Integer(tempInteger));
			}
			boolean tempBoolean = eiColumn.isPrimaryKey();
			if (tempBoolean) {
				jsonColumn.put("primaryKey", Boolean.valueOf(tempBoolean));
			}
			if (!(tempBoolean = eiColumn.isNullable())) {
				jsonColumn.put("nullable", Boolean.valueOf(tempBoolean));
			}
			if ((tempInteger = eiColumn.getWidth()) > 0) {
				jsonColumn.put("width", new Integer(tempInteger));
			}
			if ((tempInteger = eiColumn.getHeight()) > 0) {
				jsonColumn.put("height", new Integer(tempInteger));
			}
			tempString = eiColumn.getAlign();
			if ((tempString != null) && (!"left".equals(tempString))) {
				jsonColumn.put("align", tempString);
			}
			tempString = eiColumn.getDisplayType();
			if ((tempString != null) && (!"text".equals(tempString))) {
				jsonColumn.put("displayType", tempString);
			}
			tempString = eiColumn.getDateFormat();
			if ((tempString != null) && (!"yyyy-mm-dd".equals(tempString))) {
				jsonColumn.put("dateFormat", tempString);
			}
			tempString = eiColumn.getValidateType();
			if ((tempString != null) && (!"text".equals(tempString))) {
				jsonColumn.put("validateType", tempString);
			}
			tempString = eiColumn.getDefaultStringValue();
			if ((tempString != null) && (!"".equals(tempString))) {
				jsonColumn.put("defaultValue", tempString);
			}
			if ((tempString = eiColumn.getValidateErrorPrompt()) != null) {
				jsonColumn.put("errorPrompt", tempString);
			}
			if (!(tempBoolean = eiColumn.isVisible())) {
				jsonColumn.put("visible", Boolean.valueOf(tempBoolean));
			}
			if ((tempBoolean = eiColumn.isReadonly())) {
				jsonColumn.put("readonly", Boolean.valueOf(tempBoolean));
			}
			if ((tempString = eiColumn.getLabelProperty()) != null) {
				jsonColumn.put("labelProperty", tempString);
			}
			if ((tempString = eiColumn.getValueProperty()) != null) {
				jsonColumn.put("valueProperty", tempString);
			}
			Map attr = eiColumn.getAttr();
			if (attr != null) {
				jsonColumn.put("attr", attr);
			}

			return jsonColumn;
		} catch (JSONException ex) {
			ourLogger.error(ex.getMessage(), ex);
			throw new IllegalStateException(ex.getMessage());
		}
	}
}
